package com.leyou.order.task;

import com.leyou.item.client.ItemClient;
import com.leyou.order.config.JwtProperties;
import com.leyou.order.entity.Order;
import com.leyou.order.entity.OrderDetail;
import com.leyou.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Component
@Slf4j
public class OrderClearInTime {


    @Autowired
    private OrderService orderService;

    @Autowired
    private ItemClient itemClient;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 定时任务的频率，30分钟
     */
    private static final long TASK_INTERVAL = 1800000;
    /**
     * 定时任务的锁自动释放时间。 \r\n
     * 一般只要大于各服务器的时钟飘移时长+任务执行时长即可。\r\n
     * 此处默认120秒。\r\n
     */
    private static final long TASK_LEASE_TIME = 120;
    /**
     * 订单超时的期限，1小时
     */
    private static final int OVERDUE_SECONDS = 3600;

    private static final String LOCK_KEY = "close:order:task:lock";


    @Scheduled(fixedDelay = 60000)
    public void clearOrder() throws InterruptedException {

        // 0.创建锁对象
        RLock lock = redissonClient.getLock(LOCK_KEY);

        try {
            // 1.获取锁
            boolean isLock = lock.tryLock(0, TASK_LEASE_TIME, TimeUnit.SECONDS);
            if(!isLock){
                // 获取锁失败，结束任务
                log.info("【清理订单任务】未能获取任务锁，结束任务。");
                return;
            }
            // 2.开始执行任务
            try {
                // 2.1计算订单清理截止时间
                Date deadline = DateTime.now().minusSeconds(OVERDUE_SECONDS).toDate();
                // 2.2清理订单


                List<Order> orders=orderService.queryOrderByStatus(1);

                //超时清理订单

                List<Order> outTimeOrders=new ArrayList<>();

                orders.forEach(order -> {
                    if (System.currentTimeMillis()-order.getCreateTime().getTime()>(20*60*1000)){
                        outTimeOrders.add(order);
                    }
                });

                if (0!=outTimeOrders.size()){

                    //1.改订单状态
                    orderService.updateStatus(outTimeOrders);

                    //2.加库存

                    //根据订单id查询订单详情
                    List<OrderDetail> orderDetails=orderService.queryOrderDetailByOrderId(outTimeOrders.stream().map(Order::getOrderId).collect(Collectors.toList()));
                    Map<Long,Integer> skusMap=new HashMap<>();

                    //需要考虑一种情况，同一时间刷出多个订单失效，并且多个订单包含了相同的商品
                    //需要加库存的是吧重复的sku的Id的商品数量，进行累加
                    orderDetails.forEach(orderDetail -> {
                        Long skuId=orderDetail.getSkuId();

                        //这个商品是否已经出现过，如果出现过，数量累加
                        if (skusMap.containsKey(skuId)){
                            Integer num=skusMap.get(skuId);
                            skusMap.put(skuId,num+orderDetail.getNum());
                        }else{
                            skusMap.put(skuId,orderDetail.getNum());}
                    });

                    itemClient.plusStock(skusMap);

                }


            } finally {
                // 任务结束，释放锁
                lock.unlock();
                log.info("【清理订单任务】任务执行完毕，释放锁。");
            }

        } catch (InterruptedException e) {
            log.error("【清理订单任务】获取任务锁异常，原因：{}", e.getMessage(), e);
        }



    }


}
